#include "manifest.h"

int get_cpu_count() {
    return sysconf(_SC_NPROCESSORS_ONLN);
}

int get_cpu_configured() {
    return sysconf(_SC_NPROCESSORS_ONLN);
}

unsigned int get_thread_affinity() {
    int mask = 0;
    pid_t tid = gettid();
    int r = syscall(__NR_sched_getaffinity, tid, sizeof(mask), &mask);
    if (r < 0) {     /* 4.2.2 Nexus return 4 instead of 0 which is number of cores */
        int err = errno;
        trace("get_thread_affinity() mask=0x%08X failed (%d) with errno=%d=0x%x", mask, r, err, err);
        mask = 0;
    }
    return mask;
}

bool set_thread_affinity(unsigned int mask) {
    int err;
    pid_t tid = gettid();
    int r = syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask);
    if (r != 0) {
        int err = errno;
        trace("set_thread_affinity(0x%08X) failed (%d) with errno=%d=0x%x", mask, r, err, err);
    }
    return r >= 0;
}

unsigned int nth_set_bit(unsigned int mask, int bit) {
    int b = 0;
    int c = 0;
    while (mask != 0 && b < (sizeof(mask) * 8)) {
        int m = (1 << b);
        if ((mask & m) != 0) {
            c++;
            if (c == bit) {
                return m;
            }
            mask ^= m;
        }
        b++;
    }
    return 0;
}
